<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>多场景</title>
        <style>
            body {
                margin: 0;
                /* 隐藏body窗口区域滚动条 */
                overflow: hidden;
            }
            .slider {
				position: absolute;
				cursor: ew-resize;

				width: 40px;
				height: 40px;
				background-color: #F32196;
				opacity: 0.7;
				border-radius: 50%;

				top: calc(50% - 20px);
				left: calc(50% - 20px);
			}
        </style>
    </head>
    <body>
        <div class="slider"></div>
        <script type="module">
            import * as THREE from 'https://cdn.skypack.dev/three@v0.130.1'
            import { OrbitControls } from 'https://cdn.skypack.dev/three@v0.130.1/examples/jsm/controls/OrbitControls.js'
            import { GLTFLoader } from 'https://cdn.skypack.dev/three@v0.130.1/examples/jsm/loaders/GLTFLoader.js'
            import Stats from 'https://cdn.skypack.dev/three@v0.130.1/examples/jsm/libs/stats.module.js'
            import {GUI} from 'https://cdn.skypack.dev/three@v0.130.1/examples/jsm/libs/dat.gui.module.js'
            
            let sliderPos = window.innerWidth / 2
            let controls = null

            let Game = {
                tickLength: 16, 				// 20Hz
                lastTick: performance.now(),	// 最后更新时间
                stopKey: 0,
                width: window.innerWidth,
                height: window.innerHeight,
                renderer: null,
                camera: null,
                sceneL: null,
                sceneR: null,
                clock: new THREE.Clock(),
                stats: new Stats(),
                init: function(){
                    this.sceneL = new THREE.Scene()
                    this.sceneL.background = new THREE.Color( 0x8FBCD4 )
                    this.sceneR = new THREE.Scene()
                    this.sceneR.background = new THREE.Color( 0xBCD48F )
                    
                    /** 相机设置  */
                    let k = this.width / this.height; //窗口宽高比
                    let s = 200; //三维场景显示范围控制系数，系数越大，显示的范围越大
                    this.camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
                    // this.camera = new THREE.PerspectiveCamera(60, this.width / this.height, 1, 1000)
                    this.camera.position.set( 0, 0, 100 )
                    this.camera.lookAt( 0, 0, 0 )
                   
                    this.lighting()

                    /** 创建场景对象Scene */
                    this.add()
                    initSliderPos()
                    /** 创建渲染器对象 */
                    this.renderer = new THREE.WebGLRenderer({
                        antialias: true
                    })
                    this.renderer.setPixelRatio( window.devicePixelRatio )
                    this.renderer.setSize(this.width, this.height)
                    this.renderer.setClearColor(0xb9d3ff, 1)
                    this.renderer.setScissorTest(true)
                    this.renderer.setAnimationLoop(render)
                    document.body.appendChild(this.renderer.domElement)
                    document.body.appendChild(this.stats.dom)
                   
                    // 创建控件对象
                    controls = new OrbitControls(this.camera, this.renderer.domElement)
                    
                    const gui = new GUI();
                    for (let key in params) {
                        if (key.endsWith("_desc")) continue
                        gui.add(params, key ).name(params[key + "_desc"]);
                    }

                    window.onresize = function () {
                        Game.width = window.innerWidth; //窗口宽度
                        Game.height = window.innerHeight; //窗口高度
                        if (Game.renderer == null) return
                        Game.renderer.setSize(Game.width, Game.height);//设置渲染区域尺寸
                        if (Game.camera == null) return
                        k = Game.width / Game.height; //窗口宽高比
                        //修改相机对象属性
                        Game.camera.left = -s * k
                        Game.camera.right = s * k
                        Game.camera.top = s
                        Game.camera.bottom = -s
                        Game.camera.aspect = k
                        Game.camera.updateProjectionMatrix()
                    }
                    document.onkeydown = function (e) {
                        e = e || window.event;  //标准化事件对象
                        let t = e.target || e.srcElement;  //获取发生事件的元素，兼容IE和DOM
                        if (e.code == "Space") {  // 按下空格键 开始/暂停
                            // if (audio.isPlaying) {
                            //     audio.stop()
                            // } else {
                            //     audio.play()
                            // }
                            // console.log("audio: " + audio.isPlaying)
                        }
                        console.log(e.code)
                    }
                }, 
                lighting: function(){
                    if (this.sceneL == null) return
                    if (this.sceneR == null) return
                    /** 光源设置  */
                    // 点光源
                    let point = new THREE.PointLight(0xffffff)
                    point.position.set(400, 200, 300); //点光源位置

                    point.castShadow = true;

                    point.shadow.mapSize.width = 1024;
                    point.shadow.mapSize.height = 1024;

                    const d = 300;

                    point.shadow.camera.left = - d;
                    point.shadow.camera.right = d;
                    point.shadow.camera.top = d;
                    point.shadow.camera.bottom = - d;

                    point.shadow.camera.far = 1000;

                    //点光源添加到场景中
                    this.sceneL.add(point.clone())
                    this.sceneR.add(point.clone())
                    //环境光
                    this.sceneL.add(new THREE.AmbientLight(0x888888))
                    this.sceneR.add(new THREE.AmbientLight(0x888888))
                },
                update: function(tFrame) {
                    if (tFrame === undefined) {
                        tFrame = performance.now()
                        Game.lastTick = performance.now()
                    }
                    let nextTick = Game.lastTick + Game.tickLength
                    let tickNum = 0
                    if (tFrame > nextTick) {
                        tickNum = Math.floor((tFrame - Game.lastTick) / Game.tickLength)
                    }
                    Game.lastTick = tFrame
                    this.stats.update()
                },
                add: function() {
                    let axisHelper = new THREE.AxesHelper(250)
                    this.sceneL.add(axisHelper)
                    this.sceneR.add(axisHelper)

                    let meshL = new THREE.Mesh(
                        new THREE.BoxGeometry(100, 100, 100), 
                        new THREE.MeshPhongMaterial({
                            color: 0xaaccdd,
                            side: THREE.DoubleSide, //两面可见
                            transparent: true,
                        }))
                    let meshR = new THREE.Mesh(
                        new THREE.BoxGeometry(100, 100, 100), 
                        new THREE.MeshPhongMaterial({
                            wireframe: true,
                            side: THREE.DoubleSide, //两面可见
                            transparent: true,
                        }))
                    this.sceneL.add(meshL)
                    this.sceneR.add(meshR)

                }
            }

            function initSliderPos() {
                let slider = document.querySelector('.slider')
                slider.style.touchAction = 'none'
                let pointerDown = function(event) {
                    if ( event.isPrimary === false ) return
                    if (controls) controls.enabled = false
                    window.addEventListener("pointermove", pointerMove)
                    window.addEventListener("pointerup", pointerUp)
                }
                let pointerMove = function(event) {
                    if ( event.isPrimary === false ) return
                    sliderPos = Math.max(0, Math.min(window.innerWidth, event.pageX))
                    slider.style.left = (sliderPos - slider.offsetWidth / 2) + "px"
                }
                
                let pointerUp = function(event) {
                    if (controls) controls.enabled = true
                    window.removeEventListener("pointermove", pointerMove)
                    window.removeEventListener("pointerup", pointerUp)
                }
                slider.addEventListener("pointerdown", pointerDown)
            }

            function render(tFrame) {
                // clock.getDelta()方法获得两帧的时间间隔
                // mixer.update(clock.getDelta())
                Game.update()
                //执行渲染操作   指定场景、相机作为参数
                Game.renderer.setScissor( 0, 0, sliderPos, window.innerHeight )
                Game.renderer.render(Game.sceneL, Game.camera);

                Game.renderer.setScissor(sliderPos, 0, window.innerWidth, window.innerHeight )
                Game.renderer.render(Game.sceneR, Game.camera);
                // Game.stopKey = requestAnimationFrame(render)
            }
            const params = {
                // enableWind: true,
                // enableWind_desc: 'Enable wind',
                // showBall: false,
                // showBall_desc: 'Show ball',
                // togglePins: togglePins
            }
            Game.init()
            render()
            // const controls = new OrbitControls(camera, renderer.domElement);//创建控件对象
        </script>
    </body>
</html>